package model.dto

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import model.enums.MsgContentItemType
import model.repository.UserRepository
import model.vo.MessageVO
import java.lang.reflect.Type


/**
 * @author wei kunJie
 * @date 2024/4/21 16:35:12
 */
data class MessageDTO(
    val id: Long? = null,
    val time: String? = null,
    val contentItemList: List<MsgContentItem>? = null,
    val userToken: String? = null,
    val userName: String? = null,
    val userAvatar: String? = null,
    val toUserAccount: String? = null,
    val isGroup: Boolean? = null
)


class MessageSqlDTO {
    var id: String? = null
    var time: String? = null
    var content: String? = null
    var userAccount: String? = null
    var userName: String? = null
    var userAvatar: String? = null
    var toUserAccount: String? = null
    var isGroup: Boolean? = null
    val loginUserAccount: String = UserRepository.user?.account.toString()

    constructor(){}
    constructor(messageVO: MessageVO) {
        this.id = messageVO.id.toString()
        this.time = messageVO.time
        this.content = Gson().toJson(messageVO.contentItemList)
        this.userAccount = messageVO.fromUserAccount
        this.userName = messageVO.fromUserName
        this.userAvatar = messageVO.fromUserAvatar
        this.isGroup = messageVO.isGroup
        this.toUserAccount = loginUserAccount
    }

    constructor(messageDTO: MessageDTO) {
        this.id = messageDTO.id.toString()
        this.time = messageDTO.time
        this.content = Gson().toJson(messageDTO.contentItemList)
        this.userAccount = loginUserAccount
        this.userName = messageDTO.userName
        this.userAvatar = messageDTO.userAvatar
        this.isGroup = messageDTO.isGroup
        this.toUserAccount = messageDTO.toUserAccount
    }

    fun getMsgContent(msgContentItems: List<MsgContentItem>): String {
        val contentStringBuilder = StringBuilder()
        msgContentItems.forEach { contentItem ->
            if (contentItem.type == MsgContentItemType.text || contentItem.type == MsgContentItemType.url) {
                contentStringBuilder.append(contentItem.context)
            } else {
                contentStringBuilder.append("[${contentItem.type}]")
            }
        }
        return contentStringBuilder.toString()
    }

    fun getMsgContent(): String {
        val gson = Gson()
        val listType: Type = object : TypeToken<List<MsgContentItem?>?>() {}.type
        val msgContentItems: List<MsgContentItem> = gson.fromJson(content, listType)
        val contentStringBuilder = StringBuilder()
        msgContentItems.forEach { contentItem ->
            if (contentItem.type == MsgContentItemType.text || contentItem.type == MsgContentItemType.url) {
                contentStringBuilder.append(contentItem.context)
            } else {
                contentStringBuilder.append("[${contentItem.type}]")
            }
        }
        return contentStringBuilder.toString()
    }
}

data class MsgContentItem(
    val type: String? = null,
    val context: String? = null,
    val bytes: ByteArray? = null
) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as MsgContentItem

        if (type != other.type) return false
        if (context != other.context) return false
        if (bytes != null) {
            if (other.bytes == null) return false
            if (!bytes.contentEquals(other.bytes)) return false
        } else if (other.bytes != null) return false

        return true
    }

    override fun hashCode(): Int {
        var result = type?.hashCode() ?: 0
        result = 31 * result + (context?.hashCode() ?: 0)
        result = 31 * result + (bytes?.contentHashCode() ?: 0)
        return result
    }
}
